package com.rla.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.rla.common.core.page.TableDataInfo;
import com.rla.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rla.common.utils.SecurityUtils;
import com.rla.common.utils.StringUtils;
import com.rla.service.IBaseHealthTargetRuleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.rla.domain.bo.EhsEverydayWeightBo;
import com.rla.domain.vo.EhsEverydayWeightVo;
import com.rla.domain.EhsEverydayWeight;
import com.rla.mapper.EhsEverydayWeightMapper;
import com.rla.service.IEhsEverydayWeightService;

import java.math.BigDecimal;
import java.util.*;

/**
 * 日常记录-体重记录Service业务层处理
 *
 * @author rla
 * @date 2025-09-11
 */
@RequiredArgsConstructor
@Service
public class EhsEverydayWeightServiceImpl implements IEhsEverydayWeightService {

    private final EhsEverydayWeightMapper baseMapper;

    private final IBaseHealthTargetRuleService iBaseHealthTargetRuleService;

    /**
     * 查询日常记录-体重记录
     */
    @Override
    public EhsEverydayWeightVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询日常记录-体重记录列表
     */
    @Override
    public TableDataInfo<EhsEverydayWeightVo> queryPageList(EhsEverydayWeightBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EhsEverydayWeight> lqw = buildQueryWrapper(bo);
        Page<EhsEverydayWeightVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询日常记录-体重记录列表
     */
    @Override
    public List<EhsEverydayWeightVo> queryList(EhsEverydayWeightBo bo) {
        LambdaQueryWrapper<EhsEverydayWeight> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<EhsEverydayWeight> buildQueryWrapper(EhsEverydayWeightBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EhsEverydayWeight> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getUserId()), EhsEverydayWeight::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getMeasuredTime()), EhsEverydayWeight::getMeasuredTime, bo.getMeasuredTime());
        lqw.eq(StringUtils.isNotBlank(bo.getWeight()), EhsEverydayWeight::getWeight, bo.getWeight());
        lqw.eq(StringUtils.isNotBlank(bo.getHeight()), EhsEverydayWeight::getHeight, bo.getHeight());
        lqw.eq(StringUtils.isNotBlank(bo.getBmi()), EhsEverydayWeight::getBmi, bo.getBmi());
        lqw.eq(StringUtils.isNotBlank(bo.getSourceType()), EhsEverydayWeight::getSourceType, bo.getSourceType());
        lqw.like(StringUtils.isNotBlank(bo.getSourceName()), EhsEverydayWeight::getSourceName, bo.getSourceName());
        lqw.eq(StringUtils.isNotBlank(bo.getIsLook()), EhsEverydayWeight::getIsLook, bo.getIsLook());
        lqw.eq(StringUtils.isNotBlank(bo.getDeviceCode()), EhsEverydayWeight::getDeviceCode, bo.getDeviceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getBusinessId()), EhsEverydayWeight::getBusinessId, bo.getBusinessId());
        lqw.eq(StringUtils.isNotBlank(bo.getColor()), EhsEverydayWeight::getColor, bo.getColor());
        lqw.eq(bo.getFgcCreatedate() != null, EhsEverydayWeight::getFgcCreatedate, bo.getFgcCreatedate());
        lqw.eq(StringUtils.isNotBlank(bo.getFgcLastmodifier()), EhsEverydayWeight::getFgcLastmodifier, bo.getFgcLastmodifier());
        lqw.eq(bo.getFgcLastmodifydate() != null, EhsEverydayWeight::getFgcLastmodifydate, bo.getFgcLastmodifydate());
        lqw.eq(StringUtils.isNotBlank(bo.getFgcCreator()), EhsEverydayWeight::getFgcCreator, bo.getFgcCreator());
        if (StringUtils.isNotBlank(bo.getTag())&&"正常".equals(bo.getTag())){
            lqw.eq(StringUtils.isNotBlank(bo.getTag()), EhsEverydayWeight::getTag, bo.getTag());
        }else if (StringUtils.isNotBlank(bo.getTag()) && "异常".equals(bo.getTag())){
            lqw.and(StringUtils.isNotBlank(bo.getTag())&& "异常".equals(bo.getTag()), w -> {
                w.eq(EhsEverydayWeight::getTag, "偏瘦").or().eq(EhsEverydayWeight::getTag, "超重").or().eq(EhsEverydayWeight::getTag, "肥胖");
            });
        }
        lqw.orderByDesc(EhsEverydayWeight::getMeasuredTime);
        return lqw;
    }

    /**
     * 新增日常记录-体重记录
     */
    @Override
    public String insertByBo(EhsEverydayWeightBo bo) {
        bo.setUserId(SecurityUtils.getUserId().toString());
        EhsEverydayWeight add = BeanUtil.toBean(bo, EhsEverydayWeight.class);
        validEntityBeforeSave(add);
        add.setCreateBy(SecurityUtils.getUserId().toString());
        add.setCreateTime(new Date());
        Map<String, Object> resultMap = iBaseHealthTargetRuleService.calculateIndicators("体重", bo.getMeasuredType(), Double.valueOf(bo.getBmi()));
        if(ObjectUtil.isNotEmpty(resultMap)){
            add.setTag(resultMap.get("tag").toString());
            add.setColor(resultMap.get("color").toString());
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }

        return add.getId();
    }

    /**
     * 修改日常记录-体重记录
     */
    @Override
    public Boolean updateByBo(EhsEverydayWeightBo bo) {
        EhsEverydayWeight update = BeanUtil.toBean(bo, EhsEverydayWeight.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(EhsEverydayWeight entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除日常记录-体重记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Map<String, Object> queryDateCompare(String id) {
        Map<String, Object> map1 = new HashMap<>();

        EhsEverydayWeightVo vo = baseMapper.selectVoById(id);
        String measuredTime = vo.getMeasuredTime();
        String weight = vo.getWeight();
        Map<String, Object> map = baseMapper.queryDateCompare(measuredTime);

        //最近一次
        if(ObjectUtil.isNotEmpty(map)){
            String weightNext = map.get("weight").toString();
            BigDecimal subtract = new BigDecimal(weight).subtract(new BigDecimal(weightNext));
            map1.put("lastDiff", subtract);
            map1.put("lastDate", map.get("measuredTimeFormat").toString());
            if (subtract.compareTo(BigDecimal.ZERO) > 0){
                map1.put("lastFlag", "1");
            }else {
                map1.put("lastFlag", "0");
            }
        }else {
            map1.put("lastFlag", "0");
            map1.put("lastDiff", "-");
            map1.put("lastDate", "-");
        }

        //近10天
        DateTime parse = DateUtil.parse(measuredTime);
        String dateStr = DateUtil.offsetDay(parse, -10).toDateStr();
        Map<String, Object> mapTen = baseMapper.queryDateCompare(dateStr);
        if (ObjectUtil.isNotEmpty(mapTen)){
            String weightTen = mapTen.get("weight").toString();
            BigDecimal subtract = new BigDecimal(weight).subtract(new BigDecimal(weightTen));
            map1.put("tenDaysDiff", subtract);
            map1.put("tenDaysDate", mapTen.get("measuredTimeFormat").toString());
            String dateStr1 = measuredTime;
            Date date1 = DateUtil.parse(dateStr1);

            String dateStr2 = mapTen.get("measuredTime").toString();
            Date date2 = DateUtil.parse(dateStr2);

            long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
            map1.put("betweenDay", betweenDay);

            if (subtract.compareTo(BigDecimal.ZERO) > 0){
                map1.put("tenDaysFlag", "1");
            }else {
                map1.put("tenDaysFlag", "0");
            }
        }else {
            map1.put("tenDaysFlag", "0");
            map1.put("tenDaysDiff", "-");
            map1.put("tenDaysDate", "-");
            map1.put("betweenDay", "-");
        }


        return map1;
    }
}
